<template lang="" >
    <div class="file-manager" v-loading="loading" ref="fileContainer" style="height: calc(100vh - 100px);width: 100%">
        <div class="card-header">当前位置：{{currentPath}}</div>
        <el-row :gutter="10" class="mb8">
         <el-col :span="1.5">
            <el-button
               plain
               icon="Back"
               @click="handleBack"
            >返回上级</el-button>
         </el-col>
         <el-col :span="1.5">
            <el-button
               plain
               icon="Refresh"
               @click="handleEefresh"
            >刷新</el-button>
         </el-col>
         <el-col :span="1.5">
            <el-button
               type="primary"
               plain
               icon="UploadFilled"
               @click="handleUpload"
            >上传文件</el-button>
         </el-col>
         <el-col :span="1.5">
            <el-button
               type="success"
               plain
               icon="Management"
               @click="handleManagement"
            >目录管理</el-button>
         </el-col>
      </el-row>
      <el-divider></el-divider>
        <div class="card-body" @contextmenu.prevent="openRightMenu($event)">
            <div v-for="item in files" :key="item.id" class="file-list-item" @click="handleFileClick(item,$event)">

                <div class="file-list-img">
                <img v-if="item.isImg" :src="item.url" />
                <img v-else :src="`/src/assets/expFileInfo/img/`+item.type+`.png`" />
                </div>

                <div class="file-list-name" >
                <span v-if="item.isDir">{{ item.name }}</span>
                <span v-else>{{ item.name }}.{{ item.suffix }}</span>
                </div>
            </div>
            <div v-if="files.length <= 0" class="list-empty">
                <el-empty description="没有文件">
                </el-empty>
            </div>
        </div>
    </div>
     <!-- 目录管理对话框 -->
     <el-dialog title="目录管理" v-model="openManager" width="500px"  :style="{ maxHeight: '800px', overflowY: 'auto' }"  append-to-body>
        <DirManageModal @childGetList="getList" />
         <template #footer>
            <div class="dialog-footer">
               <el-button @click="cancelManager">取 消</el-button>
            </div>
         </template>
      </el-dialog>

    <!-- 导入对话框 -->
	<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body :close-on-click-modal="false">
	   <el-upload
	      ref="uploadRef"
	      :limit="10"
	      :headers="upload.headers"
	      :action="upload.url+'?dirIds='+currentDirId"
	      :disabled="upload.isUploading"
	      :on-progress="handleFileUploadProgress"
	      :on-success="handleFileSuccess"
	      :auto-upload="false"
          :multiple="true"
	      drag
	   >
	      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
	      <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
	   </el-upload>
	   <template #footer>
	      <div class="dialog-footer">
	         <el-button type="primary" @click="submitFileForm">确 定</el-button>
	         <el-button @click="upload.open = false">取 消</el-button>
	      </div>
	   </template>
	</el-dialog>

    <!-- 左击文件菜单 -->
    <ul v-show="lMenuVisible" :style="{ left: mouseX + 'px', top: mouseY + 'px' , position: 'absolute'}" class="contextmenu">
      <li @click="fileView()">
        <Memo style="width: 1em; height: 1em;" /> 预览
      </li>
      <li @click="fileCopy()">
        <DocumentCopy style="width: 1em; height: 1em;" /> 复制
      </li>
      <li  @click="moveFile()">
        <Location style="width: 1em; height: 1em;" /> 移动
      </li>
      <li  @click="fileRename()">
        <EditPen style="width: 1em; height: 1em;" /> 重命名
      </li>
      <li @click="downloadFile()">
        <Download style="width: 1em; height: 1em;" /> 下载
      </li>
      <li @click="delFile(currentObject.url)">
        <CloseBold style="width: 1em; height: 1em;" /> 删除
      </li>
    </ul>

    <!-- 右击文件夹菜单 -->
    <ul v-show="rMenuVisible" :style="{ left: mouseX + 'px', top: mouseY + 'px' , position: 'absolute'}" class="contextmenu">
      <li @click="folderAdd()">
        <FolderAdd style="width: 1em; height: 1em;" /> 新建文件夹
      </li>
    </ul>
     <!-- 新建文件夹对话框 -->
     <el-dialog title="新建文件夹" v-model="newFloderOpen" width="440px" append-to-body>

    <el-form :model="newFloderForm" ref="newFloderRef" :inline="true" >
    <el-form-item label="文件夹名称" prop="name">
        <el-input
        v-model="newFloderForm.name"
        style="width: 300px"
        />
    </el-form-item>

    </el-form>
    <template #footer>
    <div class="dialog-footer">
        <el-button type="primary" @click="submitNewFloder">提 交</el-button>
        <el-button @click="closeNewFloder">取 消</el-button>
    </div>
    </template>
    </el-dialog>

     <!-- 重命名弹窗 -->
     <el-dialog title="重命名" v-model="renameOpen" width="440px" append-to-body>

        <el-form :model="renameForm" ref="renameRef" :inline="true" >
         <el-form-item label="当前名称" prop="name">
            <el-input
               v-model="renameForm.name"
               readonly
			   style="width: 300px"
            />
         </el-form-item>
         <el-form-item label="修改名称" prop="rename">
            <el-input
               v-model="renameForm.rename"
			   style="width: 300px"
            />
         </el-form-item>

      </el-form>
         <template #footer>
	      <div class="dialog-footer">
	         <el-button type="primary" @click="submitRename">提 交</el-button>
	         <el-button @click="closeRename">取 消</el-button>
	      </div>
	   </template>
      </el-dialog>

     <!-- 移动选择文件夹弹窗 -->
     <el-dialog :title="'将 ' + moveTitle + ' 移动到:'" v-model="moveOpen" width="500px" append-to-body>
        <el-form :model="moveForm" ref="moveRef" :inline="true" >
            <el-form :model="queryMoveParams" ref="queryMoveRef" :inline="true">
                <el-form-item label="节点名称" prop="fileName">
                    <el-input
                    v-model="queryMoveParams.fileName"
                    placeholder="请输入节点内容"
                    clearable
                     style="width: 200px"
                    />
                </el-form-item>
            </el-form>
            <el-tree
                ref="moveTreeRef"
                style="max-width: 600px"
                :data="moveDataSource"
                :props="treeProps"
                node-key="id"
                default-expand-all
                show-checkbox
                :check-strictly="true"
                :expand-on-click-node="false"
                :filter-node-method="filterNode"
                @check-change="handleNodeClick"
                >
                <template #default="{ node, data }">
                    <span class="custom-tree-node">
                    <span class="truncate">
                        <el-icon v-show="data.isDir"><Folder color="#F5C800" /></el-icon>
                        <el-icon v-show="!data.isDir"><Document color="#F5C800"/></el-icon>
                        {{ node.label }}</span>
                    </span>
                </template>
                </el-tree>

        </el-form>
        <template #footer>
        <div class="dialog-footer">
            <el-button type="primary" @click="submitMove">提 交</el-button>
            <el-button @click="closeMove">取 消</el-button>
        </div>
        </template>
    </el-dialog>


</template>
<script setup name="fileManager">
import { getCurrentInstance } from '@vue/runtime-core';
const { proxy } = getCurrentInstance();
import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus'
import { ref,reactive,watch  } from 'vue';
import { listFile,getDirs,updateByName,deleteByUrl,addFolder,move,getDirTree } from "./fileManagerApi";
import DirManageModal from './DirManagerModal.vue';
//当前路径、id、对象
const currentPath = ref('/');
const currentDirId = ref('/');
const currentObject = ref({});
const files =ref([]);   
const loading = ref(false);
// 渲染文件列表
function getList(dirIds) {
    if (!dirIds) {
        dirIds = currentDirId.value;
    }
    let queryParams=ref({
        dirIds: dirIds
    });
    listFile(queryParams.value).then(response => {
        files.value =response.data; 
         //演示数据
    files.value=[
  {
    "id": -2063519742,
    "url": null,
    "name": "视频",
    "fileName": null,
    "suffix": null,
    "isImg": false,
    "isDir": true,
    "size": null,
    "type": "dir",
    "putTime": null,
    "createTime": "2025-01-03T10:13:51.000+08:00",
    "parentId": -1,
    "source": null,
    "flag": 0,
    "rename": null,
    "dirIds": null
  },
  {
    "id": -1702809598,
    "url": null,
    "name": "音乐",
    "fileName": null,
    "suffix": null,
    "isImg": false,
    "isDir": true,
    "size": null,
    "type": "dir",
    "putTime": null,
    "createTime": "2025-01-03T10:13:47.000+08:00",
    "parentId": -1,
    "source": null,
    "flag": 0,
    "rename": null,
    "dirIds": null
  },
  {
    "id": -1233047551,
    "url": null,
    "name": "文件",
    "fileName": null,
    "suffix": null,
    "isImg": false,
    "isDir": true,
    "size": null,
    "type": "dir",
    "putTime": null,
    "createTime": "2025-01-03T10:13:39.000+08:00",
    "parentId": -1,
    "source": null,
    "flag": 0,
    "rename": null,
    "dirIds": null
  },
  {
    "id": -528461822,
    "url": null,
    "name": "其他",
    "fileName": null,
    "suffix": null,
    "isImg": false,
    "isDir": true,
    "size": null,
    "type": "dir",
    "putTime": null,
    "createTime": "2025-01-06T09:39:35.000+08:00",
    "parentId": -1,
    "source": null,
    "flag": 0,
    "rename": null,
    "dirIds": null
  },
  {
    "id": 624992257,
    "url": null,
    "name": "游戏",
    "fileName": null,
    "suffix": null,
    "isImg": false,
    "isDir": true,
    "size": null,
    "type": "dir",
    "putTime": null,
    "createTime": "2025-01-03T13:45:06.000+08:00",
    "parentId": -1,
    "source": null,
    "flag": 0,
    "rename": null,
    "dirIds": null
  },
  {
    "id": -419409919,
    "url": "http://127.0.0.1:9000/test/2025/01/06/微信图片_20250103160846_20250106132915A003.jpg",
    "name": "微信图片_20250103160846",
    "fileName": "2025/01/06/微信图片_20250103160846_20250106132915A003.jpg",
    "suffix": "jpg",
    "isImg": true,
    "isDir": false,
    "size": 83771,
    "type": "jpg",
    "putTime": "2025-01-06T13:29:16.000+08:00",
    "createTime": "2025-01-06T13:29:16.000+08:00",
    "parentId": -1,
    "source": null,
    "flag": 0,
    "rename": null,
    "dirIds": null
  }
    ];
     });
  


   
}
getList();




//文件点击事件
function handleFileClick(item,event) {
    if (item.isDir) {
        getDirsAndList(item.id);
    } else {
        currentObject.value=item;
        openMenu(event); 
    }
}




  //获取目录以及加载文件列表
function getDirsAndList(id) {
    const queryParams=ref({
        id: id
    });
    getDirs(queryParams.value).then(response => {
        currentPath.value = response.data.dirs;
        currentDirId.value = response.data.dirIds;
        getList(response.data.dirIds);
    });
 }


//返回上一级
function handleBack(){
    if(currentPath.value=='/'){
        ElMessage.warning("已经是根目录");
    }else{
        currentPath.value = currentPath.value.substring(0, currentPath.value.lastIndexOf('/'));
        currentDirId.value = currentDirId.value.substring(0, currentDirId.value.lastIndexOf('/'));
        if (!currentDirId.value) {
            currentPath.value = '/';
            currentDirId.value = '/';
        }
        getList(currentDirId.value);
    }
}

//刷新
function handleEefresh(){
    loading.value=true;
    getList(currentDirId.value);
    loading.value=false;
}


//上传
function handleUpload() {
    upload.open=true;
}
/*** 导入参数 */
const upload = reactive({
  // 是否显示弹出层
  open: false,
  // 弹出层标题
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + "自己拿自己的token-getToken()" },
  // 上传的地址
  url: import.meta.env.VITE_APP_BASE_API + "/expropriation/expFile/upload"
});
/** 导入按钮操作 */
function handleImport() {
  upload.title = "文件上传";
  upload.open = true;
};
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
  upload.isUploading = true;
};
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
  upload.open = false;
  upload.isUploading = false;
  proxy.$refs["uploadRef"].handleRemove(file);
  if(response.code==200){
    getList();
  }else{
    ElMessage.error(response.msg);
  }
};
/** 提交上传文件 */
function submitFileForm() {
  proxy.$refs["uploadRef"].submit();
};


//左击菜单事件
const lMenuVisible = ref(false);
function  openMenu(e) {
    lMenuVisible.value=true;
    getMenuXY(e);
}
watch(lMenuVisible, (value) => {
  if (value) {
    //设置延时
    setTimeout(() => {
        document.body.addEventListener('click', closeMenu)
    },300)
  } else {
    document.body.removeEventListener('click', closeMenu)
  }
})

//关闭菜单（包括左击菜单和右击菜单）
function closeMenu() {
    lMenuVisible.value = false;
    rMenuVisible.value = false;
    currentObject.value={};
}

//清除数据
function clearData() {
    currentObject.value={};
    Object.assign(renameForm.value, {
      id: '',
      name: '',
      rename: ''
    });
    Object.assign(newFloderForm.value, {
      dirIds: '',
      name: ''
    });
}


//右击新建文件夹
const rMenuVisible = ref(false);
function  openRightMenu(e) {
    rMenuVisible.value=true;
    getMenuXY(e);
}
watch(rMenuVisible, (value) => {
  if (value) {
    //设置延时
    setTimeout(() => {
        document.body.addEventListener('click', closeMenu)
    },300)
  } else {
    document.body.removeEventListener('click', closeMenu)
  }
})


//计算右击菜单时的位置
const windowW = ref(document.documentElement.clientWidth);
const windowH = ref(document.documentElement.clientHeight);
window.addEventListener("resize", () => {
  windowW.value = document.documentElement.clientWidth;
  windowH.value = document.documentElement.clientHeight;
});

const mouseX=ref(0);
const mouseY=ref(0);
function getMenuXY(e){
    const menuMinWidth = 105
    const offsetLeft =  document.documentElement.clientWidth; // container margin left
    const $container = proxy.$refs.fileContainer
    const offsetWidth = $container.offsetWidth // container width
    const maxLeft = offsetLeft - menuMinWidth // left boundary
    const l = e.clientX - offsetLeft+offsetWidth + 45 // 15: margin right
    if (l > maxLeft) {
        mouseX.value = maxLeft
    } else {
        mouseX.value = l
    }
     // 高度放不下生成新的位置
    if (e.clientY > windowH.value -340) {
        mouseY.value = windowH.value - 340
    }else{
        mouseY.value=e.clientY-70+window.scrollY;
    }
}


//新建文件夹
const newFloderOpen=ref(false);
const newFloderForm = ref({
    dirIds: '',
    name: '',
});
function folderAdd(){
    newFloderOpen.value=true;
}
function closeNewFloder(){
    newFloderOpen.value=false;
    clearData();
}
function submitNewFloder(){
    const queryParams=ref({
        dirIds: currentDirId.value,
        name: newFloderForm.value.name
    });
    addFolder(queryParams.value).then(response => {
        closeNewFloder();
        getList();
        ElMessage.success("操作成功");
    });
}



//预览功能
function fileView() {
    ElMessage.warning("预览功能需集成在线预览工具");
}
//复制功能
async function fileCopy() {
    await navigator.clipboard.writeText(currentObject.value.url);
    ElMessage.success("复制成功");
}

//重命名
const renameOpen=ref(false);
const renameForm = ref({
    id: '',
    name: '',
    rename: ''
});
function fileRename() {
    renameOpen.value=true;
    renameForm.value.name=currentObject.value.name+"."+currentObject.value.suffix;
    renameForm.value.id=currentObject.value.id;
}
function closeRename(){
    renameOpen.value=false;
    clearData();
}
function submitRename(){
    updateByName(renameForm.value).then(response => {
        getList();
        closeRename();
    });
}

//下载文件
function downloadFile() {
    ElMessage.success("下载自己实现接口")
}

//删除文件
function delFile(url) {
    ElMessageBox.confirm('确认删除此文件吗？', "系统提示", {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: "warning",
    }).then(function() {
    return deleteByUrl({url: url});
  }).then(() => {
    getList();
    ElMessage.success("删除成功");
  }).catch(() => {});
}

//目录管理
const openManager = ref(false);
function handleManagement() {
    //打开窗口
    openManager.value = true;
}
function cancelManager(){
    openManager.value = false;
}

//移动文件
const moveDataSource=reactive([]);
const moveTitle=ref('');
const moveOpen=ref(false);
const moveForm = ref({
    ids: '',
    parentId: ''
});
const queryMoveParams=reactive({
    fileName:''
});
const moveTreeRef = ref(null);
watch(queryMoveParams, (val) => {
    moveTreeRef.value.filter(val.fileName)
})
function moveFile() {
    moveOpen.value=true;
    moveTitle.value=currentObject.value.name;
    moveForm.value.ids=currentObject.value.id;
    getDirTree().then(response => {
        Object.assign(moveDataSource, response.data); 
     });
}
function closeMove(){
    moveOpen.value=false;
    Object.assign(moveForm.value, {
        ids: '',
        parentId: ''
    });
    Object.assign(moveDataSource, {});
}
function submitMove(){
    moveForm.value.parentId=moveTreeRef.value.getCheckedKeys()[0];
    if(!moveForm.value.parentId||moveForm.value.parentId==''){
        ElMessage.error("请选择父级目录");
        return;
    };
    if(moveForm.value.parentId==moveForm.value.ids){
        ElMessage.error("不能移动到自己");
        return;
    };
    move(moveForm.value).then(response => {
        getList();
        closeMove();
        ElMessage.success("移动成功");
    });
}
function  handleNodeClick(data, checked) {
    if (checked) {
        moveTreeRef.value.setCheckedKeys([data.id]); // 只选中当前点击的节点
    }
}
const treeProps=reactive({
  children: 'children',
  label: 'title',
  isLeaf:'isDir'
});
const filterNode = (value, data) => {
  if (!value) return true
  return data.title.includes(value)
}
</script>
<style scoped>
.file-manager {
    margin: 20px;
}
.card-header {
    position: relative;
    height: 42px;
    line-height: 42px;
    padding: 0 10px;
    border-bottom: 1px solid #f6f6f6;
    color: #333;
    border-radius: 2px 2px 0 0;
    font-size: 16px;
} 
.file-list-item {
    display: inline-block;
    margin-right: 15px;
    margin-bottom: 15px;
    width: 90px;
    text-align: center;
    vertical-align: top;
    color: #333;
    cursor: pointer;
    position: relative;
}   
.file-list-item .file-list-img {
    width: 90px;
    height: 90px;
    position: relative;
}
.file-list-item .file-list-name {
    word-wrap: break-word;
    text-align: center;
    line-height: normal;
    font-size: 11px;
    margin-top: 5px;
}
.file-list-item:hover {
    color: #1E9FFF;
}
.file-list-item .file-list-img img {
    width: 56px;
    height: 56px;
    margin-top: 17px;
}
.contextmenu {
    margin: 0;
    background: #fff;
    z-index: 3000;
    position: absolute;
    list-style-type: none;
    padding: 5px 0;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
    li {
      margin: 0;
      padding: 7px 16px;
      cursor: pointer;
      &:hover {
        background: #eee;
      }
    }
}
</style>